﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Research.Kinect.Nui;
using System.Windows.Controls;
using MSUS.Kinect.SkeletonTracker.Utils;

namespace MSUS.Kinect.SkeletonTracker
{
	/// <summary>
	/// Records the history of the last n frames for the entire skeleton
	/// </summary>
	public class SkeletonPositionHistory
	{
		private Dictionary<JointID, JointPositionHistory> _skeletalJointsHistory;
		public int ScreenWidth { get; set; }
		public int ScreenHeight { get; set; }
		public int HistoricNodesLength { get; set; }

		/// <summary>
		/// 
		/// </summary>
		/// <param name="historicNodesLength">The number historical Joint points to record</param>
		/// <param name="screenWidth"></param>
		/// <param name="screenHeight"></param>
		public SkeletonPositionHistory(int historicNodesLength, int screenWidth, int screenHeight)
		{
			//	set some defaults.
			ScreenWidth = screenWidth;
			ScreenHeight = screenHeight;
			HistoricNodesLength = historicNodesLength;

			//	create the list.
			_skeletalJointsHistory = new Dictionary<JointID, JointPositionHistory>();
			foreach (JointID jointId in Enum.GetValues(typeof(JointID)))
			{
				string jointName = Enum.GetName(typeof(JointID), jointId);
				_skeletalJointsHistory.Add(jointId, new JointPositionHistory(jointId, jointName, HistoricNodesLength));			
			}
		}

		/// <summary>
		/// The ShoulderCentre point used as a point of reference for gestures.
		/// </summary>
		/// <returns></returns>
		public Vector NeckVector
		{
			get
			{
				return GetJointHistory(JointID.ShoulderCenter).PositionNodes.FirstOrDefault();
			}
		}

		/// <summary>
		/// Updates all of the joint positions
		/// </summary>
		/// <param name="skeleton"></param>
		public void UpdateSkeleton(SkeletonData skeleton)
		{
			foreach (Joint joint in skeleton.Joints)
			{
				JointPositionHistory jointHistory = GetJointHistory(joint.ID);
				if (jointHistory != null)
					jointHistory.RecordPosition(joint.Position);
			}
		}

		/// <summary>
		/// Gets the history for a particular Joint
		/// </summary>
		/// <param name="jointId"></param>
		/// <returns></returns>
		public JointPositionHistory GetJointHistory(JointID jointId)
		{
			JointPositionHistory jointHistory = null;
			_skeletalJointsHistory.TryGetValue(jointId, out jointHistory);
			return jointHistory;
		}


		/// <summary>
		/// Renders WPF lines (and trails) for all skeletal joints
		/// </summary>
		/// <param name="parentCanvas"></param>
		public void RenderSkeletalHistory(Canvas parentCanvas)
		{
			foreach (var joint in _skeletalJointsHistory)
			{
				joint.Value.RenderPath(parentCanvas, ScreenWidth, ScreenHeight);
			}
		}
	}
}
